#!/usr/bin/python
# -*- coding: utf-8 -*
#Author: BruceXin bruce.xin@gmail.com
#CreateDate: 2009-06-17

#stand library import
import json
import os
import types

#third party library import
import web
import gevent
import gevent.monkey
from gevent.pywsgi import WSGIServer
gevent.monkey.patch_all()

from pygments import highlight
from pygments.lexers import get_lexer_for_filename
from pygments.formatters import HtmlFormatter

QOOXDOO_VERSION = 'qooxdoo-1.4.1-sdk'

urls = ('/s/.*', 'JsonRpcHub',
        '/%s/(.*)'%QOOXDOO_VERSION, 'QooxdooSDKFile',
        '/source/(.*)', 'StaticFile',
        '/(.*)', 'StaticFile')


root_path = '../source/'
server_version = 'CodeReview Server 0.1'

class QooxdooSDKFile:
    QOOXDOO_PATH = os.path.join('../..', QOOXDOO_VERSION)
    def GET(self, filePath):
        print filePath
        return open(os.path.join(self.QOOXDOO_PATH, filePath), 'rb').read()


class StaticFile:
    def GET(self, filePath):
        print filePath
        if not filePath:
            filePath = 'index.html'
        return open(os.path.join(root_path, filePath), 'rb').read()


class CodeReviewService:
    _filters = set([".pyc",".pyo"])
    def __init__(self, workspace=None):
        if workspace:
            self.workspace = workspace
        else:
            self.workspace = os.path.curdir

    def do_list(self, current=None):
        print 'list'
        tree = {}
        tree['files'] = []
        for f in os.listdir(self.workspace):
            _,ext = os.path.splitext(f)
            if ext not in self._filters:
                try:
                    tree['files'].append(f)
                except KeyError:
                    tree['files'] = [f]
        return tree

    def do_show(self, fileName, current=None):
        print 'show'
        lexer = get_lexer_for_filename(fileName)
        formatter = HtmlFormatter(full=True, linenos=True, cssclass='source', style='pastie')
        return highlight(open(fileName, 'rb').read(), lexer, formatter)


class JsonRpcHub:
    def __init__(self):
        self.services = {'codeReviewService':CodeReviewService()}

    def locateService(self, serviceName):
        return self.services[serviceName]

    def dispatch(self, environ, start_response):
        if environ['REQUEST_METHOD'] == 'POST':
            return self.doPost(environ, start_response)
        else:
            return '405'

    def POST(self):
        data = web.data()
        rpcParams = json.loads(data)
        print rpcParams
        error = None
        result = None
        try:
            id = rpcParams['id']
            service = self.locateService(rpcParams['service'])
            params = rpcParams['params']
            if type(params) == types.ListType:
                result = getattr(service, 'do_'+rpcParams['method'])(*params, current=None)
            elif type(params) == types.DictType:
                result = getattr(service, 'do_'+rpcParams['method'])(current=None, **params)
            else:
                error = 403
        except Exception:
            import traceback
            traceback.print_exc()
            error = -1

        data = json.dumps({'id':id, 'error':error, 'result':result})
        return data


if __name__ == '__main__':
    app = web.application(urls, globals()).wsgifunc()
    WSGIServer(('',8080), application=app).serve_forever()




